# coding=utf-8
from neatHealthScripts.bedcore.server import ServerSystem, compFactory, levelId
from neatHealthScripts.modInfo import ModInfo
from neatHealthScripts.server.config import PlayerConfig


class MainSystem(ServerSystem):
    gameComp = compFactory.CreateGame(levelId)

    def __init__(self, namespace, systemName):
        super(MainSystem, self).__init__(namespace, systemName)
        self.playerConfigMap = {}
        """:type: dict[str, PlayerConfig]"""

    def addEventListen(self, namespace, systemName):
        self.ListenForEvent(namespace, systemName, 'AddServerPlayerEvent', self, self.AddServerPlayerEvent)
        self.ListenForEvent(namespace, systemName, 'PlayerIntendLeaveServerEvent', self, self.PlayerIntendLeaveServerEvent)
        self.ListenForEvent(namespace, systemName, 'ActorHurtServerEvent', self, self.ActorHurtServerEvent)
        self.ListenForEvent(ModInfo.NAME, 'main', 'ConfigChangedEvent', self, self.ConfigChangedEvent)

    def AddServerPlayerEvent(self, args):
        """
        :type args: dict
        """
        # 玩家加入时初始化玩家配置
        player = args['id']
        self.playerConfigMap[player] = PlayerConfig()

    def PlayerIntendLeaveServerEvent(self, args):
        """
        :type args: dict
        """
        # 玩家退出时移除玩家配置
        player = args['playerId']
        self.playerConfigMap.pop(player, None)

    def ActorHurtServerEvent(self, args):
        """
        :type args: dict
        """
        # 生物受伤时将信息同步至附近玩家
        damage = args['damage']
        if damage <= 0:
            return
        entity = args['entityId']
        world = compFactory.CreateDimension(entity).GetEntityDimensionId()
        players = []
        for player, config in self.playerConfigMap.items():
            if not config.showHurt:
                continue
            if compFactory.CreateDimension(player).GetEntityDimensionId() != world:
                continue
            if not self.gameComp.CanSee(player, entity, config.maxDistance, True, 180, 360):
                continue
            players.append(player)
        if not players:
            return
        self.NotifyToMultiClients(players, 'EntityHurtEvent', {
            'entity': entity,
            'damage': damage,
        })

    def ConfigChangedEvent(self, args):
        """
        :type args: dict
        """
        # 同步玩家的模组配置
        player = args['__id__']
        config = self.playerConfigMap.get(player)
        if config is None:
            return
        config.deserialize(args['config'])
